using MediatR;
using SageKing.Core.Extensions;
using static System.Runtime.InteropServices.JavaScript.JSType;

namespace SageKing.Application.IceRPC.Service;

public class SageKingPackagesService : ISageKingPackagesService
{

    /// <summary>
    /// 缓存参数
    /// </summary>
    Dictionary<string, Dictionary<DataStreamTypeEnum, Dictionary<string, byte>>> CacheDataPosDic = new Dictionary<string, Dictionary<DataStreamTypeEnum, Dictionary<string, byte>>>();

    /// <summary>
    /// 客户端配置参数
    /// </summary>
    private readonly ClientTypeDicOptions ClientTypeDic;

    /// <summary>
    /// 消息列表
    /// </summary>
    private ConcurrentDictionary<string, List<StreamPackage[]>> _messagesDic;
    private ConcurrentDictionary<string, List<string>> _messagesStringDic;

    /// <summary>
    /// 客户端连接列表
    /// </summary>
    private ConcurrentDictionary<string, ClientConnectionInfo<IConnectionContext>> _clientConnectionDic;

    /// <summary>
    /// 消息结构定义
    /// </summary>
    public ConcurrentDictionary<string, SageKingMessage> sageKingMessageDic;

    /// <summary>
    /// 服务端连接器
    /// </summary>
    private readonly IClientConnectionProvider<IceRpc.ClientConnection, IceRPCClientOption, StreamPackage, Pipeline, Identity> ClientConnectionProvider;


    public SageKingPackagesService(
            IClientConnectionProvider<IceRpc.ClientConnection, IceRPCClientOption, StreamPackage, Pipeline, Identity> clientConnectionProvider,
         IOptions<ClientTypeDicOptions> clientTypeDic
        )
    {
        this.ClientTypeDic = clientTypeDic.Value;
        this._messagesDic = new ConcurrentDictionary<string, List<StreamPackage[]>>();
        this._messagesStringDic = new ConcurrentDictionary<string, List<string>>();
        this._clientConnectionDic = new ConcurrentDictionary<string, ClientConnectionInfo<IConnectionContext>>();
        this.ClientConnectionProvider = clientConnectionProvider;
        this.sageKingMessageDic = new ConcurrentDictionary<string, SageKingMessage>();
    }

    public Action<string, string, int> NoticeAction { get; set; } = (a, b, type) => { };
    public Func<string, long, Task<Dictionary<DataStreamTypeEnum, Dictionary<string, byte>>>> GetMessagePosFunc { get; set; }

    public ConcurrentDictionary<string, List<StreamPackage[]>> GetMessagesDic => _messagesDic;

    public bool OnGetMessagePosFunc { get; set; } = false;

    public ConcurrentDictionary<string, List<string>> GetMessagesStringDic => _messagesStringDic;

    public List<string> GetServerNames => ClientConnectionProvider.GetServerNames().ToList();

    public ConcurrentDictionary<string, ClientConnectionInfo<IConnectionContext>> GetClientConnectionDic => _clientConnectionDic;


    public async Task<int> PushMsgAsync(string connectionid, StreamPackage[] streams, string msgType = "Push")
    {
        if (!streams.HasItem())
        {
            return await Task.FromResult(0);
        }
        if (_clientConnectionDic.TryGetValue(connectionid, out var client))
        {
            var connection = client.GetClientReceiverProxy();
            var getdesc = ClientTypeDic.GetDesc(client.ClientType);
            var result = await connection.PushStreamPackageListAsync(streams, msgType);
        }
        return await Task.FromResult(1);
    }

    public async Task<int> SendMsgAsync(string serverName, StreamPackage[] streams, string msgType = "Send")
    {
        if (!streams.HasItem())
        {
            return await Task.FromResult(0);
        }
        var connection = this.ClientConnectionProvider.GetClientConnection(serverName);
        var getdesc = ClientTypeDic.GetDesc(connection.ServerType);
        var result = await connection.SendStreamPackageListAsync(streams, msgType);
        return await Task.FromResult(1);
    }

    public async Task<int> ReceiverMsgAsync(string msgType, StreamPackage[] streams)
    {
        if (_messagesDic.TryGetValue(msgType, out var list))
        {
            list.Add(streams);
        }
        else
        {
            _messagesDic[msgType] = new List<StreamPackage[]> { streams };
        }

        //普通消息
        var resultLstTask = await GetStringActionFrom(msgType, streams);
        var resultLst = resultLstTask ?? new List<string>();

        if (_messagesStringDic.TryGetValue(msgType, out var resultAll))
        {
            resultAll.AddRange(resultLst);
        }
        else
        {
            _messagesStringDic[msgType] = resultLst;
        }

        return await Task.FromResult(1);
    }

    public async Task<int> ClientConnectionChangeAsync(bool isAdd, ClientConnectionInfo<IConnectionContext> clientConnection)
    {
        if (isAdd)
        {
            _clientConnectionDic[clientConnection.ConnectionId] = clientConnection;
        }
        else
        {
            _clientConnectionDic.TryRemove(clientConnection.ConnectionId, out _);
        }
        return await Task.FromResult(1);
    }


    /// <summary>
    /// 获取数据
    /// </summary>
    /// <param name="msgtype"></param>
    /// <param name="packages"></param>
    /// <returns></returns>
    async Task<List<string>> GetStringActionFrom(string msgtype, StreamPackage[] packages)
    {
        List<string> resultLst = new List<string>();

        foreach (var item2 in packages)
        {
            try
            {
                if (!item2.HeadDic.TryGetValue(EntityNameConst.IceHeadDicNameKey, out var key))
                {
                    var content = item2.GetString();
                    resultLst.Add(content);
                    continue;
                };

                if (!OnGetMessagePosFunc)
                {
                    continue;
                }

                if (!CacheDataPosDic.TryGetValue(key, out var getPostDic))
                {
                    var data = key.Split("_");
                    var data2 = (data[0], data[1].ParseToLong());

                    //获取配置信息
                    var getPost = await GetMessagePosFunc?.Invoke(data2.Item1, data2.Item2);
                    if (getPost == null)
                    {
                        continue;
                    }
                    getPostDic = getPost;
                    CacheDataPosDic[key] = getPost;
                }

                if (getPostDic == null)
                {
                    continue;
                }

                //处理数据 posdic
                var getData = item2.GetStreamPackageData(getPostDic);
                var result = getData.GetContent();
                resultLst.Add(result);

            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        return resultLst;

    }
}